package org.hairball.analysis;

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.EmptyVisitor;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;

import java.util.List;

public class SingletonSniffer {
    public boolean isSingleton(ClassNode classNode) {
        List methodList = classNode.methods;
        for (Object o : methodList) {
            MethodNode method = (MethodNode) o;

            if (isStatic(method)) {
                Type returnType = Type.getReturnType(method.desc);
                ASMClassDescriptorFilter filter = new ASMClassDescriptorFilter();
                String returnTypeName = filter.filter(returnType.getClassName());
                String definingClassName = filter.filter(classNode.name);

                final boolean[] accessingStaticVariable = new boolean[]{false};
                if ((returnTypeName.equals(definingClassName))) {
                    method.accept((MethodVisitor) new EmptyVisitor() {
                        public void visitFieldInsn(int i, String string, String string1, String string2) {
                           accessingStaticVariable[0] = (Opcodes.GETSTATIC & i) != 0;
                        }
                    });
                }
                return accessingStaticVariable[0];
            }
        }
        return false;
    }

    private boolean isStatic(MethodNode method) {
        return ((Opcodes.ACC_STATIC & method.access) != 0);
    }
}
